package com.avit.tv.kui.pro.volume;

import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import com.avit.tv.kui.R;
import com.avit.tv.kui.pro.AvitVolumeView;
import com.avit.tv.kui.pro.utils.KeyCodeChecks;
import com.avit.tv.kui.utils.Log;
import com.avit.tv.kui.utils.Utils;

import java.lang.ref.WeakReference;
import java.lang.reflect.Method;

/**
 * 音量条类目
 *
 * @author like
 * @date 2020/8/29
 */
public class AvitVolumeController {

    private AudioManager manager;
    /**
     * 静音的view
     */
    private ImageView muteView;

    /**
     * 音量总控的type
     */
    private int streamType;

    private VolumeListener volume;

    private WindowManager windowManager;
    private WindowManager.LayoutParams progressLayoutParams;
    private WindowManager.LayoutParams muteLayoutParams;

    private KeyCodeChecks volumeDownCheck;
    private KeyCodeChecks volumeUpCheck;
    private KeyCodeChecks muteKeycode;
    private int radix;
    private VolumeHandler volumeHandler;
    /**
     * 设置音量最大极值
     */
    private int maxValue;

    /**
     * 当前音量的值
     */
    private int currentValue;

    /**
     * 公因子
     */
    private float percent;

    /**
     * 系统最大值
     */
    private int streamMaxVolume;

    /**
     * 单纯基数记数
     */
    private int tempCent;

    /**
     * 手动判断是否按下了静音
     */
    private boolean isMute;

    /**
     * 是否进行静音调控，如果否，则不需要进行静音调控
     */
    private boolean isMuteControl;

    /**
     * 监听progress view 显示和消失
     */
    private VolumeShownListener volumeShownListener;

    /**
     * 多次进行音量调节操作
     */
    private float deepRow;

    private AvitVolumeController() {
        isMuteControl = true;
    }


    private volatile static AvitVolumeController volumeController;

    public static AvitVolumeController getInstance() {
        if (volumeController == null) {
            synchronized (AvitVolumeController.class) {
                if (volumeController == null) {
                    volumeController = new AvitVolumeController();
                }
            }
        }
        return volumeController;
    }

    /**
     * 初始化系统音量
     */
    public void initSystemVolume(Context context) {
        initContextMethod(context);
        initResources();
        initVolumeValues();
        initProgressLayout();
        initMuteLayout();
        calculateCurrentValue();
        initVolumeView();
        initMute();
    }


    /**
     * 初始化Context 相关内容量
     *
     * @param context
     */
    private void initContextMethod(Context context) {
        manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        muteView = new ImageView(context);
        streamType = AudioManager.STREAM_MUSIC;
        if (null == volume)
            volume = new AvitVolumeView(context);
        windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        radix = Utils.getRadix(context);
        Utils.setSvgImageRes(muteView, ContextCompat.getDrawable(context, R.drawable.ic_mute), Color.LTGRAY);
    }


    /**
     * 初始化资源
     */
    private void initResources() {
        volumeDownCheck = new KeyCodeChecks.CodesBuilder().initKeyCode(KeyEvent.KEYCODE_VOLUME_DOWN).build();
        volumeUpCheck = new KeyCodeChecks.CodesBuilder().initKeyCode(KeyEvent.KEYCODE_VOLUME_UP).build();
        muteKeycode = new KeyCodeChecks.CodesBuilder().initKeyCode(KeyEvent.KEYCODE_VOLUME_MUTE).build();
        progressLayoutParams = new WindowManager.LayoutParams();
        muteLayoutParams = new WindowManager.LayoutParams();
        volumeHandler = new VolumeHandler(new WeakReference<>(this));
    }

    /**
     * 初始化音量相关参数
     */
    private void initVolumeValues() {
        streamMaxVolume = manager.getStreamMaxVolume(streamType);
        if (maxValue == 0)
            maxValue = streamMaxVolume;
        percent = maxValue * 1f / streamMaxVolume;
        if (percent < 1)
            deepRow = 1 / percent;
    }

    /**
     * 初始化静音模块
     */
    private void initMute() {
        isMute = isSystemMute();
        if (isMute && isMuteControl) {
            volumeHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    showProgress(false);
                }
            }, 1000L);
        }
    }

    /**
     * 更新音量条相关内容
     */
    private void initVolumeView() {
        volume.setMoveValue(maxValue);
        volume.onProgress(currentValue);
        volume.onCurrentVolume(currentValue, maxValue);
    }

    /**
     * 计算当前音量位置
     */
    private void calculateCurrentValue() {
        int currentVolume = manager.getStreamVolume(streamType);
        if (currentVolume < streamMaxVolume)
            currentValue = Math.round(percent * currentVolume);
        else
            currentValue = maxValue;
        Log.w(this, "current volume:" + currentVolume + "===== current percent" + percent);
    }


    /**
     * 判断是否静音
     *
     * @return
     */
    private boolean isSystemMute() {
        boolean isStreamMute = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            isStreamMute = manager.isStreamMute(AudioManager.STREAM_MUSIC);
        } else {
            try {
                Method isStreamMuteMethod = AudioManager.class.getMethod("isStreamMute", int.class);
                isStreamMute = (boolean) isStreamMuteMethod.invoke(manager, AudioManager.STREAM_MUSIC);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        Log.d(this, "isStreamMute: " + isStreamMute);
        return isStreamMute;
    }

    private void initProgressLayout() {
        initDefaultLayoutParams(progressLayoutParams);
        progressLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        progressLayoutParams.height = 30 * radix;
        progressLayoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
        progressLayoutParams.verticalMargin = 0.13f;
    }

    private void initMuteLayout() {
        initDefaultLayoutParams(muteLayoutParams);
        muteLayoutParams.width = 30 * radix;
        muteLayoutParams.height = 30 * radix;
        muteLayoutParams.gravity = Gravity.TOP | Gravity.END;
        muteLayoutParams.horizontalMargin = 0.05f;
        muteLayoutParams.verticalMargin = 0.05f;
    }


    public void initDefaultLayoutParams(WindowManager.LayoutParams layoutParams) {
        layoutParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        layoutParams.format = PixelFormat.TRANSPARENT;
        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
    }

    /**
     * 自定义音量进度条的布局设置
     *
     * @param progressLayoutParams
     */
    public void setProgressLayoutParams(WindowManager.LayoutParams progressLayoutParams) {
        this.progressLayoutParams = progressLayoutParams;
    }

    /**
     * 禁音图标的布局设置
     *
     * @param muteLayoutParams
     */
    public void setMuteLayoutParams(WindowManager.LayoutParams muteLayoutParams) {
        this.muteLayoutParams = muteLayoutParams;
    }

    /**
     * 自定义初始化音量减小按键值
     *
     * @param volumeDownCheck
     */
    public void setVolumeDownCheck(KeyCodeChecks volumeDownCheck) {
        this.volumeDownCheck = volumeDownCheck;
    }

    /**
     * 自定义初始化音量增大按键值
     *
     * @param volumeUpCheck
     */
    public void setVolumeUpCheck(KeyCodeChecks volumeUpCheck) {
        this.volumeUpCheck = volumeUpCheck;
    }

    /**
     * 自定义静音键值
     *
     * @param muteKeycode
     */
    public void setMuteKeycode(KeyCodeChecks muteKeycode) {
        this.muteKeycode = muteKeycode;
    }

    /**
     * 设置静音的资源图标
     *
     * @param res
     */
    public void setMuteDrawable(@DrawableRes int res) {
        if (null != muteView) muteView.setImageResource(res);
    }

    /**
     * 设置静音颜色
     *
     * @param color
     * @param context
     */
    public void setMuteColor(@ColorInt int color, Context context) {
        if (null != muteView)
            Utils.setSvgImageRes(muteView, ContextCompat.getDrawable(context, R.drawable.ic_mute), color);
    }

    public boolean onKey(KeyEvent event) {
        boolean tempCheck = false;
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (volumeDownCheck.checkKeycode(event.getKeyCode())) {
                tempCheck = true;
                initVolumeUI(false);
                dealVolume(false);
                isMute = false;
            } else if (volumeUpCheck.checkKeycode(event.getKeyCode())) {
                tempCheck = true;
                initVolumeUI(true);
                dealVolume(true);
                isMute = false;
            } else if (muteKeycode.checkKeycode(event.getKeyCode())) {
                tempCheck = true;
                setSystemMute(!isSystemMute());
                showProgress(!isSystemMute());
                isMute = isSystemMute();
                calculateCurrentValue();
            }
            initVolumeView();
        } else {
            if (volumeDownCheck.checkKeycode(event.getKeyCode()) || volumeUpCheck.checkKeycode(event.getKeyCode()) || muteKeycode.checkKeycode(event.getKeyCode())) {
                volumeHandler.delayDismiss();
            }
        }
        return tempCheck;
    }

    private void initVolumeUI(boolean isUp) {
        volume.isProgressUp(isUp);
        setSystemMute(false);
        if (isMute)
            calculateCurrentValue();
        showProgress(true);
        if (isUp && maxValue >= currentValue + 1) {
            currentValue += 1;
        } else if (!isUp && 0 <= currentValue - 1) {
            currentValue -= 1;
        } else if (isUp && currentValue + 1 > maxValue) {
            currentValue = maxValue;
        } else
            currentValue = 0;
    }

    private void dealVolume(boolean isUp) {
        tempCent += 1;
        if (deepRow < 1) deepRow = 1;
        if (tempCent > percent) {
            for (int i = 0; i < deepRow; i++) {
                if (isUp)
                    manager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0);
                else
                    manager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, 0);
            }
            tempCent = 0;
        }
    }

    /**
     * 显示对应的view
     *
     * @param root
     * @param layoutParams
     */
    private void show(View root, WindowManager.LayoutParams layoutParams) {
        try {
            if (root.getParent() == null)
                windowManager.addView(root, layoutParams);
            else
                windowManager.updateViewLayout(root, layoutParams);
        } catch (Exception e) {
            Log.e(this, "error:" + e.getMessage());
        }
    }

    /**
     * 删除对应的view
     *
     * @param root
     */
    private void dismiss(View root) {
        try {
            if (root.getParent() != null)
                windowManager.removeViewImmediate(root);
        } catch (Exception e) {
            Log.e(this, "remove error:" + e.getMessage());
        }
    }

    /**
     * 设置静音
     *
     * @param mute
     */
    private void setSystemMute(boolean mute) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            manager.adjustStreamVolume(AudioManager.STREAM_MUSIC, mute ? AudioManager.ADJUST_MUTE : AudioManager.ADJUST_UNMUTE, 0);
        } else {
            manager.setStreamMute(AudioManager.STREAM_MUSIC, mute);
        }
    }


    /**
     * 判断直接显示什么控件
     *
     * @param isShowProgress
     */
    private void showProgress(boolean isShowProgress) {
        if (isShowProgress) {
            volumeHandler.removeDelayCallback();
            dismiss(muteView);
            if (volumeShownListener != null) volumeShownListener.onShown();
            show(volume.getVolumeView(), progressLayoutParams);
        } else {
            dismiss(volume.getVolumeView());
            show(muteView, muteLayoutParams);
            if (volumeShownListener != null) volumeShownListener.onDismiss();
        }
    }

    /**
     * 设定volume 样式
     *
     * @param bgDrawable
     * @param iconSize
     * @param iconColor
     * @param progressColor
     */
    public void initVolumebar(Drawable bgDrawable, int iconSize, int iconColor, int progressColor) {
        if (null != bgDrawable)
            volume.getVolumeView().setBackground(bgDrawable);
        if (iconSize != 0)
            volume.setIconSize(iconSize);
        if (iconColor != -1)
            volume.setIconColor(iconColor);
        if (progressColor != -1)
            volume.setProgressColor(progressColor);
    }

    /**
     * 主显示问题监听处理
     */
    private static class VolumeHandler extends Handler {

        private final int DELAY_DISMISS = 0XFFFF;
        private final long DELAY_TIME = 3500L;
        private WeakReference<AvitVolumeController> reference;

        public VolumeHandler(WeakReference<AvitVolumeController> reference) {
            this.reference = reference;
        }

        private void removeDelayCallback() {
            removeMessages(DELAY_DISMISS);
        }


        private void delayDismiss() {
            removeMessages(DELAY_DISMISS);
            sendEmptyMessageDelayed(DELAY_DISMISS, DELAY_TIME);
        }

        private boolean isContentGet() {
            return null != reference && reference.get() != null;
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == DELAY_DISMISS && isContentGet()) {
                reference.get().dismiss(reference.get().volume.getVolumeView());
                VolumeShownListener volumeShownListener = reference.get().volumeShownListener;
                if (volumeShownListener != null)
                    volumeShownListener.onDismiss();
            }
        }

    }

    /**
     * 设置streamType
     *
     * @param streamType
     */
    public void setStreamType(int streamType) {
        this.streamType = streamType;
    }

    /**
     * 用来完全自定义其他的类型的View
     *
     * @param volume
     * @return
     */
    public AvitVolumeController setVolume(VolumeListener volume) {
        this.volume = volume;
        return this;
    }

    /**
     * 设置最大值
     *
     * @param maxValue
     * @return
     */
    public AvitVolumeController setMaxValue(int maxValue) {
        this.maxValue = maxValue;
        return this;
    }

    /**
     * 回收
     */
    public void release() {
        if (volume.getVolumeView() != null)
            dismiss(volume.getVolumeView());
        if (muteView != null)
            dismiss(muteView);
        if (volumeHandler != null)
            volumeHandler.removeCallbacksAndMessages(null);
        if (volume != null)
            volume = null;
        maxValue = 0;
    }

    /**
     * 控制是否调控静音
     * 有的盒子隔离了静音按键
     *
     * @param muteControl
     * @return
     */
    public AvitVolumeController setMuteControl(boolean muteControl) {
        isMuteControl = muteControl;
        return this;
    }

    /**
     * 设置显示和消失的监听
     *
     * @param volumeShownListener
     */
    public void setVolumeShownListener(VolumeShownListener volumeShownListener) {
        this.volumeShownListener = volumeShownListener;
    }

    /**
     * 强制dismiss volume
     */
    public void dismissVolumeUI(){
        dismiss(volume.getVolumeView());
        if (volumeShownListener!=null)
            volumeShownListener.onDismiss();
    }
}
